package com.paradogs.generator.protobuf;


import com.baidu.bjf.remoting.protobuf.ProtobufIDLGenerator;
import com.paradogs.framework.annotations._scan.BaseScanner;
import com.paradogs.framework.annotations._scan.BaseSelector;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author: yumi
 * @date: 2023/11/18  10:55
 * @Description: TODO
 */
@Slf4j
@Component
public class ProtoFileSelector extends BaseSelector {

    @Setter
    private String generatorDir;

    @Setter
    private String[] scanPackages;

    private Set<Class<?>> cachedTypes = new LinkedHashSet<>();

    private Set<Class<?>> cachedEnumTypes = new LinkedHashSet<>();

    @Override
    public String[] getScanPackages() {
        return scanPackages;
    }

    @Override
    public BaseScanner getScanner(BeanFactory beanFactory) {
        return new ProtoFileScanner((DefaultListableBeanFactory) beanFactory);
    }

    @Override
    public void handle(BeanDefinition beanDefinition) {
    }

    /** 生成 .proto 文件 */
    @Override
    public void handle(Set<BeanDefinition> beanDefinitions) {
        try {
            List<Class<?>> list = beanDefinitions.stream().map(beanDefinition -> {

                        try {
                            return Class.forName(beanDefinition.getBeanClassName());
                        } catch (ClassNotFoundException e) {
                            throw new RuntimeException(e);
                        }
                    })
                    .distinct()
                    .collect(Collectors.toList());

            // 生成 .proto
            Map<String, String> codeMap = ProtobufIDLGenerator.getIDL(list);

            // 写入
            for (Map.Entry<String, String> entry : codeMap.entrySet()) {
                String filename = entry.getKey();
                String code = entry.getValue();
                Path targetDirectory = ResourceUtils.getFile(this.generatorDir).toPath();
                Path filePath = targetDirectory.resolve(filename);
                Files.createDirectories(targetDirectory); // 确保目录存在
                Files.write(filePath, code.getBytes());
                log.info("生成文件: {}/{}", generatorDir, filename);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }



}
